home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / gui / uberwidgets / simplemenu.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  29KB  |  813 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. from gui.toolbox import Monitor
  6. import wx
  7. import sys
  8. from wx import Bitmap, Rect, RectS, RectPS, GetMousePosition, MenuEvent, Point, VERTICAL, HORIZONTAL, Pen, Brush, Size
  9. from gui.skin.skinobjects import SkinColor, Margins
  10. from gui.windowfx import fadein
  11. from gui import skin
  12. from util import do, Delegate
  13. from common import pref
  14. from gui.uberwidgets import UberWidget
  15. from gui.textutil import GetTextWidth, default_font
  16. from gui.windowfx import DrawSubMenuArrow, ApplySmokeAndMirrors
  17. from logging import getLogger
  18. log = getLogger('simplemenu')
  19.  
  20. class SMDTimer(wx.Timer):
  21.     
  22.     def __init__(self, menu):
  23.         self.menu = menu
  24.         wx.Timer.__init__(self)
  25.  
  26.     
  27.     def Start(self, hitrect, *args, **kwargs):
  28.         self.hitrect = hitrect
  29.         self.args = args
  30.         self.kwargs = kwargs
  31.         wx.Timer.Start(self, 500, True)
  32.  
  33.     
  34.     def Notify(self):
  35.         if not (self.menu.Shown) and self.hitrect.Contains(wx.GetMousePosition()):
  36.             self.menu.Display(*self.args, **self.kwargs)
  37.         
  38.  
  39.  
  40.  
  41. class RecapTimer(wx.Timer):
  42.     
  43.     def __init__(self, target):
  44.         wx.Timer.__init__(self)
  45.         self.target = target
  46.         self.Start(10)
  47.  
  48.     
  49.     def Notify(self):
  50.         target = self.target
  51.         mp = target.Parent.ScreenToClient(wx.GetMousePosition())
  52.         if (not target.Rect.Contains(mp) or target.ClientRect.Contains(mp)) and not wx.GetMouseState().LeftDown():
  53.             self.Stop(target)
  54.         
  55.  
  56.     
  57.     def Stop(self, target):
  58.         wx.Timer.Stop(self)
  59.         target.Parent.CascadeCapture()
  60.         del target.recaptimer
  61.  
  62.  
  63.  
  64. class SimpleMenuSpine(wx.VListBox, UberWidget):
  65.     
  66.     def __init__(self, parent, skin):
  67.         wx.VListBox.__init__(self, parent)
  68.         UberWidget.__init__(self, 'LISTBOX')
  69.         self.MinSize = wx.Size(1, 1)
  70.         events = [
  71.             (wx.EVT_PAINT, self.OnPaint),
  72.             (wx.EVT_MOUSEWHEEL, self.OnMouseWheel),
  73.             (wx.EVT_MOTION, self.OnMouseMove),
  74.             (wx.EVT_LEFT_UP, self.OnLUp),
  75.             (wx.EVT_LEFT_DOWN, self.OnLDown),
  76.             (wx.EVT_RIGHT_DOWN, self.OnLDown),
  77.             (wx.EVT_MIDDLE_DOWN, self.OnLDown),
  78.             (wx.EVT_LEFT_DCLICK, (lambda e: pass)),
  79.             (wx.EVT_SCROLLWIN, self.OnScroll),
  80.             (wx.EVT_MOUSE_CAPTURE_LOST, self.OnMouseCaptureLost)]
  81.         (do,)((lambda .0: for event, method in .0:
  82. self.Bind(event, method))(events))
  83.         self.itemheight = 20
  84.         self.items = []
  85.         self.ItemCount = len(self.items)
  86.         self.SetSkinKey(skin, True)
  87.  
  88.     
  89.     def OnMouseCaptureLost(self, e):
  90.         self.Parent.CloseRoot()
  91.  
  92.     
  93.     def UpdateSkin(self):
  94.         key = self.skinkey
  95.         self.native = native = not key
  96.         if native:
  97.             self.OpenNativeTheme()
  98.             self.padding = wx.Point(2, 2)
  99.             self.framesize = Margins([
  100.                 1,
  101.                 1,
  102.                 1,
  103.                 1])
  104.             sz = self.Parent.Sizer
  105.             if sz:
  106.                 sz.Detach(1)
  107.                 sz.Detach(1)
  108.                 sz.Add(wx.Size(self.framesize.left, self.framesize.top), (0, 0))
  109.                 sz.Add(wx.Size(self.framesize.right, self.framesize.bottom), (2, 2))
  110.             
  111.             self.framebg = None
  112.             self.menubg = None
  113.             self.itembg = None
  114.             self.selbg = None
  115.             self.Font = default_font()
  116.             self.normalfc = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWTEXT)
  117.             self.selfc = wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
  118.             self.MakeNativeSubmenuIcons()
  119.             self.separator = None
  120.         else:
  121.             self.CloseNativeTheme()
  122.             
  123.             s = lambda k, default: skin.get('%s.%s' % (key, k), default)
  124.             self.padding = s('padding', wx.Point(2, 2))
  125.             self.framesize = s('framesize', Margins([
  126.                 0,
  127.                 0,
  128.                 0,
  129.                 0]))
  130.             sz = self.Parent.Sizer
  131.             if sz:
  132.                 sz.Detach(1)
  133.                 sz.Detach(1)
  134.                 sz.Add(wx.Size(self.framesize.left, self.framesize.top), (0, 0))
  135.                 sz.Add(wx.Size(self.framesize.right, self.framesize.bottom), (2, 2))
  136.             
  137.             self.framebg = s('frame', (lambda : SkinColor(wx.BLACK)))
  138.             self.menubg = s('backgrounds.menu', None)
  139.             self.itembg = s('backgrounds.item', None)
  140.             self.selbg = s('backgrounds.selection', None)
  141.             self.Font = s('font', default_font())
  142.             self.normalfc = s('fontcolors.normal', (lambda : wx.BLACK))
  143.             self.selfc = s('fontcolors.selection', (lambda : wx.BLACK))
  144.             submenuicon = self.submenuicon = s('submenuicon', None)
  145.             if submenuicon is None:
  146.                 self.MakeNativeSubmenuIcons()
  147.             else:
  148.                 self.submenuiconhot = s('submenuiconhover', submenuicon)
  149.             self.separator = s('separatorimage', None)
  150.         for item in self.items:
  151.             if item.menu:
  152.                 item.menu.spine.SetSkinKey(key)
  153.                 continue
  154.         
  155.  
  156.     
  157.     def MakeNativeSubmenuIcons(self):
  158.         arrowmask = wx.EmptyBitmap(10, 10)
  159.         mdc = wx.MemoryDC()
  160.         mdc.SelectObject(arrowmask)
  161.         controls = controls
  162.         import gui.windowfx
  163.         arect = wx.Rect(0, 0, 10, 10)
  164.         DrawSubMenuArrow(mdc, arect)
  165.         mdc.SelectObject(wx.NullBitmap)
  166.         mdc2 = wx.MemoryDC()
  167.         for s in xrange(2):
  168.             acolor = None if s else self.normalfc
  169.             arrow = wx.EmptyBitmap(10, 10)
  170.             arrow.SetMask(wx.Mask(arrowmask, wx.WHITE))
  171.             mdc2.SelectObject(arrow)
  172.             mdc2.Brush = wx.Brush(acolor)
  173.             mdc2.FloodFill(0, 0, wx.BLACK)
  174.             mdc2.SelectObject(wx.NullBitmap)
  175.             if s:
  176.                 self.submenuiconhot = arrow
  177.                 continue
  178.             self.submenuicon = arrow
  179.         
  180.  
  181.     
  182.     def DrawNativeBackgroundFallback(self, dc, part, state, unusedrect):
  183.         rect = wx.RectS(self.Size)
  184.         dc.Brush = Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
  185.         dc.Pen = wx.TRANSPARENT_PEN
  186.         dc.DrawRectangleRect(rect)
  187.  
  188.     
  189.     def OnPaint(self, event):
  190.         dc = wx.BufferedPaintDC(self)
  191.         rect = wx.RectS(self.ClientSize)
  192.         if self.menubg:
  193.             self.menubg.Draw(dc, rect)
  194.         else:
  195.             dc.SetClippingRect(rect)
  196.             nrect = wx.Rect(*rect)
  197.             nrect.Inflate(1, 1)
  198.             self.DrawNativeLike(dc, 0, 0, nrect, self.DrawNativeBackgroundFallback)
  199.             dc.DestroyClippingRegion()
  200.         rect.Height = self.itemheight
  201.         i = self.FirstVisibleLine
  202.         j = self.LastVisibleLine
  203.         if j >= 0 and j != sys.maxint * 2 + 1:
  204.             bg = self.OnDrawBackground
  205.             draw = self.OnDrawItem
  206.             measure = self.OnMeasureItem
  207.             for n in xrange(i, j + 1):
  208.                 bg(dc, rect, n)
  209.                 draw(dc, rect, n)
  210.                 rect.SetY(rect.GetY() + measure(n))
  211.             
  212.         
  213.  
  214.     
  215.     def OnDrawBackground(self, dc, rect, n):
  216.         if self.native:
  217.             if self.GetSelection() == n:
  218.                 dc.Brush = wx.Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
  219.                 dc.Pen = wx.TRANSPARENT_PEN
  220.                 dc.DrawRectangleRect(rect)
  221.             
  222.         elif self.GetSelection() == n and self.selbg:
  223.             self.selbg.Draw(dc, rect)
  224.         elif self.itembg:
  225.             self.itembg.Draw(dc, rect)
  226.         
  227.  
  228.     
  229.     def OnDrawItem(self, dc, rect, n):
  230.         curser = Point(rect.x, rect.y) + (self.padding.x, 0)
  231.         if self.items[n].id == -1:
  232.             return self.DrawSeparator(dc, rect, n)
  233.         
  234.         if self.items[n].font:
  235.             font = self.items[n].font
  236.         else:
  237.             font = self.Font
  238.         dc.Font = font
  239.         dc.TextForeground = None if self.Selection == n else self.normalfc
  240.         if self.items[n].menu:
  241.             dc.Brush = wx.BLACK_BRUSH
  242.             dc.Pen = wx.TRANSPARENT_PEN
  243.             smi = None if self.Selection == n else self.submenuicon
  244.             dc.DrawBitmap(smi, rect.Width - self.padding.x - smi.Width, rect.Y + rect.Height / 2 - smi.Height / 2, True)
  245.             endcap = smi.Width + self.padding.x
  246.         else:
  247.             endcap = 0
  248.         padx = self.padding.x
  249.         txtext = dc.Font.Height
  250.         txtext_pad = Point(txtext + padx, 0)
  251.         for i in self.items[n].content:
  252.             if type(i) is Bitmap:
  253.                 curser.y = rect.Y + (rect.height / 2 - i.Height / 2)
  254.                 imgpad = None if self.bitmapwidth else 0
  255.                 dc.DrawBitmapPoint(i, (curser.x + imgpad, curser.y), True)
  256.                 curser += Point(max(self.bitmapwidth, i.Width) + padx, 0)
  257.                 continue
  258.             if isinstance(i, basestring):
  259.                 curser.y = rect.Y + (rect.height / 2 - txtext / 2)
  260.                 text_rect = RectPS(curser, Size(rect.width - curser.x - padx - endcap, txtext))
  261.                 dc.DrawTruncatedText(i, text_rect, alignment = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
  262.                 curser += txtext_pad
  263.                 continue
  264.         
  265.  
  266.     
  267.     def DrawSeparator(self, dc, rect, n):
  268.         sepwidth = rect.width - self.padding.x * 2
  269.         if self.separator:
  270.             sepheight = self.separator.Size.height
  271.             seppos = (self.padding.x, rect.y + rect.height // 2 - sepheight // 2)
  272.             self.separator.Draw(dc, RectPS(seppos, (sepwidth, sepheight)))
  273.         else:
  274.             dc.Pen = Pen(self.normalfc, 1)
  275.             seppos = Point(self.padding.x, rect.y + rect.height // 2)
  276.             endpos = seppos + Point(sepwidth, 0)
  277.             dc.DrawLinePoint(seppos, endpos)
  278.  
  279.     
  280.     def OnMouseWheel(self, event):
  281.         self.ScrollLines(event.WheelRotation // abs(event.WheelRotation))
  282.  
  283.     
  284.     def OnMouseMove(self, event):
  285.         mp = self.ScreenToClient(GetMousePosition())
  286.         items = self.items
  287.         if self.ClientRect.Contains(mp):
  288.             n = self.HitTest(mp)
  289.             if self.Selection != n:
  290.                 do((lambda .0: for item in .0:
  291. if item.menu and item.menu.IsShown():
  292. item.menu.Show(False)continue)(self.items))
  293.                 if items[n].id != -1:
  294.                     self.SetSelection(n)
  295.                     if items[n].menu:
  296.                         items[n].menu.DelayedDisplay(self.GetItemRect(n), self)
  297.                     
  298.                 else:
  299.                     self.SetSelection(-1)
  300.             
  301.         elif self.Rect.Contains(mp):
  302.             self.Parent.CascadeRelease()
  303.             self.recaptimer = RecapTimer(self)
  304.         else:
  305.             self.SetSelection(-1)
  306.             gp = self.GrandParent
  307.             if isinstance(gp, SimpleMenu) and gp.CheckParentalContact(GetMousePosition()):
  308.                 gp.spine.AddPendingEvent(event)
  309.             
  310.  
  311.     
  312.     def OnLUp(self, event):
  313.         if self.GetClientRect().Contains(event.Position):
  314.             n = self.HitTest(event.Position)
  315.             if self.items[n].id != -1:
  316.                 item = self.items[n]
  317.                 if not item.menu:
  318.                     self.TriggerItem(item)
  319.                 
  320.             
  321.         
  322.  
  323.     
  324.     def TriggerItem(self, item):
  325.         if item.method is not None:
  326.             wx.CallAfter(item.method, item)
  327.         elif self.Parent.callback:
  328.             wx.CallAfter(self.Parent.callback, item)
  329.         else:
  330.             menuevent = MenuEvent(wx.wxEVT_COMMAND_MENU_SELECTED, item.id)
  331.             self.Parent.AddPendingEvent(menuevent)
  332.         self.Parent.CloseRoot()
  333.  
  334.     
  335.     def OnLDown(self, event):
  336.         if not self.Rect.Contains(event.Position) and not self.Parent.CheckParentalContact(wx.GetMousePosition(), True):
  337.             self.Parent.CloseRoot()
  338.         
  339.  
  340.     
  341.     def OnScroll(self, event):
  342.         self.Refresh()
  343.         event.Skip()
  344.  
  345.     
  346.     def CalcSize(self):
  347.         self.CalcItemHeight()
  348.         if self.Parent.staticwidth:
  349.             width = self.Parent.width
  350.         else:
  351.             self.CalcItemWidth()
  352.             width = self.calcedwidth
  353.         if not (self.Parent.maxheight) or self.ItemCount < self.Parent.maxheight:
  354.             height = self.itemheight * self.ItemCount
  355.         else:
  356.             height = self.itemheight * self.Parent.maxheight
  357.         maxwidth = self.Parent.maxwidth
  358.         if maxwidth and width > maxwidth:
  359.             width = maxwidth
  360.         
  361.         minwidth = self.Parent.minwidth
  362.         if minwidth and width < minwidth:
  363.             width = minwidth
  364.         
  365.         p = self.Parent.ScreenRect[:2]
  366.         self.Parent.Rect = RectPS(p, wx.Size(width, height + self.framesize.y))
  367.  
  368.     
  369.     def CalcItemHeight(self):
  370.         hset = list((lambda .0: for item in .0:
  371. if item.font:
  372. item.font.Heightcontinue)(self.items))
  373.         hset.append(self.Font.Height)
  374.         if max(hset) - min(hset) > 10:
  375.             hset = sorted(hset)
  376.             lhset = len(hset)
  377.             
  378.             def Median(set):
  379.                 lset = len(set)
  380.                 if lset % 2:
  381.                     m1 = lset // 2
  382.                     m2 = m1 + 1
  383.                     return set[m1] + (set[m2] - set[m1]) // 2
  384.                 else:
  385.                     return set[lset // 2 + 1]
  386.  
  387.             q1 = Median(hset[:lhset // 2])
  388.             q3 = Median(hset[lhset // 2 + 1:])
  389.             iqr = q3 - q1
  390.             hi = q3 + 1.5 * iqr
  391.             hset = (set,)((lambda .0: for h in .0:
  392. if h < hi:
  393. hcontinue)(hset))
  394.         
  395.         self.bitmapwidth = bitmapwidth = 0
  396.         for item in self.items:
  397.             if item.id == -1:
  398.                 pass
  399.             elif item.content and isinstance(item.content[0], Bitmap):
  400.                 bitmapwidth = max(bitmapwidth, item.content[0].Width)
  401.             
  402.             for object in item.content:
  403.                 if type(object) is Bitmap:
  404.                     hset.append(object.Height)
  405.                     continue
  406.             
  407.         
  408.         if bitmapwidth:
  409.             empty_bitmap = wx.EmptyBitmap(bitmapwidth, 1)
  410.             for item in self.items:
  411.                 if item.id == -1:
  412.                     continue
  413.                 if item.content and isinstance(item.content[0], basestring):
  414.                     item.content.insert(0, empty_bitmap)
  415.                     continue
  416.             
  417.             self.bitmapwidth = bitmapwidth
  418.         
  419.         h = max(hset)
  420.         for item in self.items:
  421.             if item.font and item.font.Height > h:
  422.                 self.items.remove(item)
  423.                 continue
  424.         
  425.         self.ItemCount = len(self.items)
  426.         self.itemheight = h + 2 * self.padding.y
  427.  
  428.     
  429.     def CalcItemWidth(self):
  430.         if not self.items:
  431.             self.calcedwidth = 0
  432.         else:
  433.             wset = (set,)((lambda .0: for item in .0:
  434. item.GetContentWidth(self.Parent))(self.items))
  435.             w = max(wset)
  436.             w += self.framesize.x
  437.             self.calcedwidth = w
  438.  
  439.     
  440.     def OnMeasureItem(self, n):
  441.         return self.itemheight
  442.  
  443.     
  444.     def GetSelectionRect(self):
  445.         return self.GetItemRect(self.Selection)
  446.  
  447.     
  448.     def GetItemRect(self, n):
  449.         pos = self.ScreenRect.Position
  450.         x = pos.x
  451.         width = self.Size.x
  452.         y = pos.y + (sum,)((lambda .0: for i in .0:
  453. self.OnMeasureItem(i))(xrange(n)))
  454.         height = self.OnMeasureItem(n)
  455.         return Rect(x, y, width, height)
  456.  
  457.  
  458.  
  459. class SimpleMenu(wx.PopupTransientWindow, UberWidget):
  460.     
  461.     def __init__(self, parent, skinkey = 'simplemenu', maxheight = None, width = 0, minwidth = 0, maxwidth = 0, callback = None):
  462.         wx.PopupTransientWindow.__init__(self, parent)
  463.         self.BeforeDisplay = Delegate()
  464.         Bind = self.Bind
  465.         Bind(wx.EVT_PAINT, self.OnPaint)
  466.         Bind(wx.EVT_SIZE, self.OnSize)
  467.         Bind(wx.EVT_SHOW, self.OnClose)
  468.         Bind(wx.EVT_MENU, self.PassEvent)
  469.         self.maxheight = maxheight
  470.         self.staticwidth = bool(width)
  471.         self.width = width
  472.         self.maxwidth = maxwidth
  473.         self.minwidth = minwidth
  474.         self.spine = SimpleMenuSpine(self, skinkey)
  475.         self.displaytimer = SMDTimer(self)
  476.         s = self.Sizer = wx.GridBagSizer()
  477.         s.SetEmptyCellSize(wx.Size(0, 0))
  478.         s.AddGrowableCol(1, 1)
  479.         s.AddGrowableRow(1, 1)
  480.         s.Add(self.spine, (1, 1), flag = wx.EXPAND)
  481.         s.Add(wx.Size(self.spine.framesize.left, self.spine.framesize.top), (0, 0))
  482.         s.Add(wx.Size(self.spine.framesize.right, self.spine.framesize.bottom), (2, 2))
  483.         self.callback = callback
  484.         self.connected = None
  485.  
  486.     
  487.     def SetSkinKey(self, key):
  488.         self.spine.SetSkinKey(key)
  489.  
  490.     
  491.     def SetWidth(self, width):
  492.         self.staticwidth = True
  493.         w = width
  494.         if self.minwidth:
  495.             w = max(w, self.minwidth)
  496.         
  497.         if self.maxwidth:
  498.             w = min(w, self.maxwidth)
  499.         
  500.         self.width = w
  501.         self.Size = wx.Size(w, -1)
  502.  
  503.     
  504.     def OnSize(self, event):
  505.         event.Skip()
  506.         background = self.spine.framebg
  507.         SplitImage4 = SplitImage4
  508.         import cgui
  509.         if isinstance(background, SplitImage4):
  510.             ApplySmokeAndMirrors(self, background.GetBitmap(self.Size))
  511.         else:
  512.             ApplySmokeAndMirrors(self)
  513.         self.Layout()
  514.  
  515.     
  516.     def OnPaint(self, event):
  517.         dc = wx.PaintDC(self)
  518.         rect = wx.RectS(self.Size)
  519.         bg = self.spine.framebg
  520.         if bg:
  521.             bg.Draw(dc, rect)
  522.         elif self.spine.native:
  523.             dc.Brush = wx.TRANSPARENT_BRUSH
  524.             dc.Pen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOWFRAME))
  525.             dc.DrawRectangleRect(rect)
  526.         
  527.  
  528.     
  529.     def Insert(self, index, *args, **kwargs):
  530.         self.InsertItem(index, SimpleMenuItem(*args, **kwargs))
  531.  
  532.     
  533.     def Append(self, *args, **kwargs):
  534.         self.AppendItem(SimpleMenuItem(*args, **kwargs))
  535.  
  536.     
  537.     def InsertItem(self, index, item):
  538.         self.spine.items.insert(index, item)
  539.         self.spine.ItemCount = len(self.spine.items)
  540.  
  541.     
  542.     def AppendItem(self, item):
  543.         self.spine.items.append(item)
  544.         self.spine.ItemCount = len(self.spine.items)
  545.  
  546.     
  547.     def RemoveItem(self, item):
  548.         sp = self.spine
  549.         if isinstance(item, int):
  550.             item = sp.items[item]
  551.         
  552.         sp.Selection = -1
  553.         sp.items.remove(item)
  554.         sp.ItemCount = len(self.spine.items)
  555.  
  556.     
  557.     def RemoveAll(self):
  558.         self.spine.items = []
  559.         self.spine.ItemCount = len(self.spine.items)
  560.  
  561.     
  562.     def GetCount(self):
  563.         return len(self.spine.items)
  564.  
  565.     Count = property(GetCount)
  566.     __len__ = GetCount
  567.     
  568.     def SetSelection(self, selection):
  569.         self.spine.Selection = selection
  570.  
  571.     
  572.     def GetSelection(self):
  573.         return self.spine.Selection
  574.  
  575.     Selection = property(GetSelection, SetSelection)
  576.     
  577.     def SetItems(self, items):
  578.         if wx.IsDestroyed(self):
  579.             print >>sys.stderr, 'WARNING: %r is destroyed' % self
  580.             return None
  581.         
  582.         self.Frozen().__enter__()
  583.         
  584.         try:
  585.             sp = self.spine
  586.             sp.items = items
  587.             sp.ItemCount = len(items)
  588.             if sp.IsShownOnScreen():
  589.                 sp.RefreshAll()
  590.         finally:
  591.             pass
  592.  
  593.  
  594.     
  595.     def GetItem(self, index):
  596.         return self.spine.items[index]
  597.  
  598.     
  599.     def GetItems(self):
  600.         return self.spine.items
  601.  
  602.     
  603.     def GetItemIndex(self, item):
  604.         return self.spine.items.index(item)
  605.  
  606.     
  607.     def PassEvent(self, event):
  608.         self.Parent.AddPendingEvent(event)
  609.  
  610.     
  611.     def DelayedDisplay(self, rect, *args, **kwargs):
  612.         if not self.displaytimer.IsRunning():
  613.             self.displaytimer.Start(rect, *args, **kwargs)
  614.         
  615.  
  616.     
  617.     def Display(self, caller = None, funnle = True, funnlefullscreen = False):
  618.         self.BeforeDisplay()
  619.         if not self.IsShown():
  620.             self.spine.CalcSize()
  621.             if caller and isinstance(caller, SimpleMenuSpine):
  622.                 self.caller = None
  623.                 rect = caller.GetSelectionRect()
  624.                 position = Point(rect.x + rect.width, rect.y - self.spine.framesize.top)
  625.                 newrect = RectPS(position, self.ScreenRect.Size)
  626.                 screenrect = Monitor.GetFromRect(newrect).Geometry
  627.                 if newrect.bottom > screenrect.bottom:
  628.                     position.y = rect.y + rect.height - self.Size.height
  629.                 
  630.                 if newrect.right > screenrect.right:
  631.                     position.x = rect.x - self.Size.width
  632.                 
  633.             elif caller:
  634.                 self.caller = caller
  635.                 caller_rect = caller.ScreenRect
  636.                 position = caller_rect.BottomLeft
  637.                 newrect = RectPS(position, self.ScreenRect.Size)
  638.                 screenrect = Monitor.GetFromWindow(caller).Geometry
  639.                 if newrect.bottom > screenrect.bottom:
  640.                     position.y -= caller_rect.Height + self.spine.Size.height
  641.                 
  642.                 if newrect.right > screenrect.right:
  643.                     position.x += caller_rect.Width - self.spine.Size.width
  644.                 
  645.             else:
  646.                 self.caller = None
  647.                 position = wx.GetMousePosition()
  648.                 newrect = RectPS(position, self.ScreenRect.Size)
  649.                 screenrect = Monitor.GetFromPoint(position).Geometry
  650.                 if newrect.bottom > screenrect.bottom:
  651.                     position.y -= self.spine.Size.height
  652.                 
  653.                 if newrect.right > screenrect.right and pref('menus.shift_mode', False):
  654.                     position.x -= self.spine.Size.width
  655.                 
  656.             newrect = wx.RectPS(position, self.Size)
  657.             screenrect = Monitor.GetFromRect(newrect).Geometry
  658.             pos = None if funnle else position
  659.             self.SetRect(RectPS(pos, self.Size))
  660.             self.spine.SetSelection(-1)
  661.             fadein(self, 'xfast')
  662.             self.spine.RefreshAll()
  663.             if not self.spine.HasCapture():
  664.                 self.spine.CaptureMouse()
  665.             
  666.             wx.CallLater(10, self.Refresh)
  667.             if not isinstance(caller, SimpleMenuSpine):
  668.                 self.TopConnect()
  669.             
  670.         
  671.  
  672.     
  673.     def TopConnect(self):
  674.         t = self.Top
  675.         while not isinstance(t, wx.TopLevelWindow):
  676.             t = t.Parent.Top
  677.         id = t.Id
  678.         t.Connect(id, id, wx.wxEVT_ACTIVATE, self.OnActiveChange)
  679.         self.connected = (t, id)
  680.  
  681.     
  682.     def OnActiveChange(self, event):
  683.         self.CloseRoot()
  684.  
  685.     
  686.     def OnClose(self, event):
  687.         if not self.IsShown():
  688.             do((lambda .0: for item in .0:
  689. if item.menu and item.menu.IsShown():
  690. item.menu.Show(False)continue)(self.spine.items))
  691.             while self.spine.HasCapture():
  692.                 self.spine.ReleaseMouse()
  693.             if self.caller:
  694.                 event = wx.MenuEvent(wx.wxEVT_MENU_CLOSE, self.Id)
  695.                 self.caller.AddPendingEvent(event)
  696.                 self.caller = None
  697.             
  698.             if self.connected:
  699.                 (window, id) = self.connected
  700.                 window.Disconnect(id, id, wx.wxEVT_ACTIVATE)
  701.                 self.connected = None
  702.             
  703.         
  704.  
  705.     
  706.     def CloseRoot(self):
  707.         if isinstance(self.Parent, SimpleMenu):
  708.             self.Parent.CloseRoot()
  709.         else:
  710.             self.Show(False)
  711.  
  712.     
  713.     def __repr__(self):
  714.         return '<SimpleMenu %r>' % self.spine.items
  715.  
  716.     
  717.     def CheckParentalContact(self, pos, ignoresubmenu = False):
  718.         rect = RectS(self.spine.Size)
  719.         mp = self.spine.ScreenToClient(pos)
  720.         if rect.Contains(mp):
  721.             if ignoresubmenu and not (self.spine.items[self.spine.HitTest(mp)].menu) or not self.spine.items[self.spine.HitTest(mp)].menu.IsShown():
  722.                 return True
  723.             
  724.         if isinstance(self.Parent, SimpleMenu):
  725.             return self.Parent.CheckParentalContact(pos, ignoresubmenu)
  726.         
  727.         return False
  728.  
  729.     
  730.     def CascadeRelease(self):
  731.         while self.spine.HasCapture():
  732.             self.spine.ReleaseMouse()
  733.         if isinstance(self.Parent, SimpleMenu):
  734.             self.Parent.CascadeRelease()
  735.         
  736.  
  737.     
  738.     def CascadeCapture(self):
  739.         if isinstance(self.Parent, SimpleMenu):
  740.             self.Parent.CascadeCapture()
  741.         
  742.         if not self.spine.HasCapture():
  743.             self.spine.CaptureMouse()
  744.         
  745.  
  746.  
  747.  
  748. class SimpleMenuItem(wx.Object):
  749.     
  750.     def __init__(self, content = '', method = None, font = None, id = None, menu = None):
  751.         if content is not None:
  752.             if isinstance(content, basestring):
  753.                 self.content = [
  754.                     content]
  755.             elif isinstance(content, list):
  756.                 self.content = content
  757.             
  758.         else:
  759.             self.content = []
  760.         self.method = method
  761.         self.menu = menu
  762.         self.font = font
  763.         self.id = id
  764.  
  765.     
  766.     def __repr__(self):
  767.         return '<SMItem %s>' % self.GetContentAsString()
  768.  
  769.     
  770.     def __str__(self):
  771.         return self.GetContentAsString()
  772.  
  773.     
  774.     def __eq__(self, o):
  775.         if isinstance(o, self.__class__):
  776.             pass
  777.         return self.content == o.content
  778.  
  779.     
  780.     def __hash__(self):
  781.         return hash(id(self))
  782.  
  783.     
  784.     def GetContentAsString(self):
  785.         for thing in self.content:
  786.             if isinstance(thing, basestring):
  787.                 return thing
  788.                 continue
  789.         
  790.         return ''
  791.  
  792.     
  793.     def GetContentWidth(self, menu):
  794.         if not menu:
  795.             return None
  796.         
  797.         pad = menu.spine.padding
  798.         if not self.font:
  799.             pass
  800.         font = menu.spine.Font
  801.         cont = self.content
  802.         count = len(cont)
  803.         w = (sum,)((lambda .0: for s in .0:
  804. if isinstance(s, basestring):
  805. GetTextWidth(s, font)continue)(cont))
  806.         w += sum((lambda .0: for b in .0:
  807. if type(b) is Bitmap:
  808. b.Widthcontinue)(cont))
  809.         w += (count + 1) * pad.x + 1
  810.         return w
  811.  
  812.  
  813.